//
// StoreNuke.Net -  http://www.storenuke.net
// Copyright (c) 2005
// by Robert J Collins ( info@storenuke.net ) of WillowTree Software, Inc. ( http://www.willowtreesoftware.com )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;

namespace StoreNuke.StarterKit.Commerce {

    //*******************************************************
    //
    // ProductDetails Class
    //
    // A simple data class that encapsulates details about
    // a particular product inside the Commerce Starter Kit Product
    // database.
    //
    //*******************************************************

    public class ProductDetails {

        public String  ModelNumber;
        public String  ModelName;
        public String  ProductImage;
        public decimal UnitCost;
        public String  Description;
		public int     CategoryID;
		public bool    Archived;
    }

    //*******************************************************
    //
    // ProductsDB Class
    //
    // Business/Data Logic Class that encapsulates all data
    // logic necessary to query products within
    // the Commerce Starter Kit Products database.
    //
    //*******************************************************

    public class ProductsDB {

        //*******************************************************
        //
        // ProductsDB.GetProductCategories() Method <a name="GetProductCategories"></a>
        //
        // The GetProductCategories method returns a DataReader that exposes all 
        // product categories (and their CategoryIDs) within the Commerce Starter Kit Products   
        // database.  The SQLDataReaderResult struct also returns the
        // SQL connection, which must be explicitly closed after the
        // data from the DataReader is bound into the controls.
        //
        // Other relevant sources:
        //     + <a href="ProductCategoryList.htm" style="color:green">ProductCategoryList Stored Procedure</a>
        //
        //*******************************************************

        public SqlDataReader GetProductCategories(bool archived) 
        {

            // Create Instance of Connection and Command Object
            SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
            SqlCommand myCommand = new SqlCommand("StoreNuke_ProductCategoryList", myConnection);

            // Mark the Command as a SPROC
			myCommand.CommandType = CommandType.StoredProcedure;

			SqlParameter parameterArchived = new SqlParameter("@Archived", SqlDbType.Bit);
			parameterArchived.Value = archived;
			myCommand.Parameters.Add(parameterArchived);

            // Execute the command
            myConnection.Open();
            SqlDataReader result = myCommand.ExecuteReader(CommandBehavior.CloseConnection);

            // Return the datareader result
            return result;
		}

		public SqlDataReader GetAllProductCategories() 
		{

			// Create Instance of Connection and Command Object
			SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
			SqlCommand myCommand = new SqlCommand("StoreNuke_ProductCategoryListAll", myConnection);

			// Mark the Command as a SPROC
			myCommand.CommandType = CommandType.StoredProcedure;

			// Execute the command
			myConnection.Open();
			SqlDataReader result = myCommand.ExecuteReader(CommandBehavior.CloseConnection);

			// Return the datareader result
			return result;
		}

		public string GetSingleProductCategoryName(int categoryID) 
		{
            // Create Instance of Connection and Command Object
			SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
			SqlCommand myCommand = new SqlCommand("StoreNuke_GetSingleProductCategory", myConnection);

			// Mark the Command as a SPROC
			myCommand.CommandType = CommandType.StoredProcedure;

			// Add Parameters to SPROC
			SqlParameter parameterCategoryID = new SqlParameter("@CategoryID", SqlDbType.Int, 4);
			parameterCategoryID.Value = categoryID;
			myCommand.Parameters.Add(parameterCategoryID);

			// Execute the command
			myConnection.Open();
			SqlDataReader result = myCommand.ExecuteReader(CommandBehavior.CloseConnection);

			string CategoryName = "";

			if(result.Read())
			{
				CategoryName = result["CategoryName"].ToString();
			}

			// Return the datareader result
			return CategoryName;
		}

		public string GetSingleProductCategoryDescription(int categoryID) 
		{
			// Create Instance of Connection and Command Object
			SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
			SqlCommand myCommand = new SqlCommand("StoreNuke_GetSingleProductCategory", myConnection);

			// Mark the Command as a SPROC
			myCommand.CommandType = CommandType.StoredProcedure;

			// Add Parameters to SPROC
			SqlParameter parameterCategoryID = new SqlParameter("@CategoryID", SqlDbType.Int, 4);
			parameterCategoryID.Value = categoryID;
			myCommand.Parameters.Add(parameterCategoryID);

			// Execute the command
			myConnection.Open();
			SqlDataReader result = myCommand.ExecuteReader(CommandBehavior.CloseConnection);

			string CategoryDesc = "";

			if(result.Read())
			{
				CategoryDesc = result["CategoryDescription"].ToString();
			}

			// Return the datareader result
			return CategoryDesc;
		}

		public SqlDataReader GetSingleProductCategory(int categoryID) 
		{
			// Create Instance of Connection and Command Object
			SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
			SqlCommand myCommand = new SqlCommand("StoreNuke_GetSingleProductCategory", myConnection);

			// Mark the Command as a SPROC
			myCommand.CommandType = CommandType.StoredProcedure;

			// Add Parameters to SPROC
			SqlParameter parameterCategoryID = new SqlParameter("@CategoryID", SqlDbType.Int, 4);
			parameterCategoryID.Value = categoryID;
			myCommand.Parameters.Add(parameterCategoryID);

			// Execute the command
			myConnection.Open();
			SqlDataReader result = myCommand.ExecuteReader(CommandBehavior.CloseConnection);

			// Return the datareader result
			return result;
		}

        //*******************************************************
        //
        // ProductsDB.GetProducts() Method <a name="GetProducts"></a>
        //
        // The GetProducts method returns a struct containing a forward-only,
        // read-only DataReader. This displays all products within a specified
        // product category.  The SQLDataReaderResult struct also returns the
        // SQL connection, which must be explicitly closed after the
        // data from the DataReader is bound into the controls.
        //
        // Other relevant sources:
        //     + <a href="ProductsByCategory.htm" style="color:green">ProductsByCategory Stored Procedure</a>
        //
        //*******************************************************

        public SqlDataReader GetProducts(int categoryID, bool archived) {

            // Create Instance of Connection and Command Object
            SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
            SqlCommand myCommand = new SqlCommand("StoreNuke_ProductsByCategory", myConnection);

            // Mark the Command as a SPROC
            myCommand.CommandType = CommandType.StoredProcedure;

            // Add Parameters to SPROC
            SqlParameter parameterCategoryID = new SqlParameter("@CategoryID", SqlDbType.Int, 4);
            parameterCategoryID.Value = categoryID;
			myCommand.Parameters.Add(parameterCategoryID);

			SqlParameter parameterArchived = new SqlParameter("@Archived", SqlDbType.Bit);
			parameterArchived.Value = archived;
			myCommand.Parameters.Add(parameterArchived);

            // Execute the command
            myConnection.Open();
            SqlDataReader result = myCommand.ExecuteReader(CommandBehavior.CloseConnection);
            
            // Return the datareader result
            return result;
        }

        public SqlDataReader GetAllProducts(int categoryID) {

            // Create Instance of Connection and Command Object
            SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
            SqlCommand myCommand = new SqlCommand("StoreNuke_ProductsByCategoryAll", myConnection);

            // Mark the Command as a SPROC
            myCommand.CommandType = CommandType.StoredProcedure;

            // Add Parameters to SPROC
            SqlParameter parameterCategoryID = new SqlParameter("@CategoryID", SqlDbType.Int, 4);
            parameterCategoryID.Value = categoryID;
			myCommand.Parameters.Add(parameterCategoryID);

            // Execute the command
            myConnection.Open();
            SqlDataReader result = myCommand.ExecuteReader(CommandBehavior.CloseConnection);
            
            // Return the datareader result
            return result;
        }

        //*******************************************************
        //
        // ProductsDB.GetProductDetails() Method <a name="GetProductDetails"></a>
        //
        // The GetProductDetails method returns a ProductDetails
        // struct containing specific details about a specified
        // product within the Commerce Starter Kit Products Database.
        //
        // Other relevant sources:
        //     + <a href="ProductDetail.htm" style="color:green">ProductDetail Stored Procedure</a>
        //
        //*******************************************************

        public ProductDetails GetProductDetails(int productID) {

            // Create Instance of Connection and Command Object
            SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
            SqlCommand myCommand = new SqlCommand("StoreNuke_ProductDetail", myConnection);

            // Mark the Command as a SPROC
            myCommand.CommandType = CommandType.StoredProcedure;

            // Add Parameters to SPROC
            SqlParameter parameterProductID = new SqlParameter("@ProductID", SqlDbType.Int, 4);
            parameterProductID.Value = productID;
            myCommand.Parameters.Add(parameterProductID);

			// Execute the command
			myConnection.Open();
			SqlDataReader result = myCommand.ExecuteReader(CommandBehavior.CloseConnection);

            // Create and Populate ProductDetails Struct using
            ProductDetails myProductDetails = new ProductDetails();

			if(result.Read())
			{
				myProductDetails.ModelNumber = result["ModelNumber"].ToString();
				myProductDetails.ModelName = result["ModelName"].ToString();
				myProductDetails.ProductImage = result["ProductImage"].ToString().Trim();
				myProductDetails.UnitCost = (decimal)result["UnitCost"];
				myProductDetails.Description = result["Description"].ToString().Trim();
				myProductDetails.CategoryID = (int)result["CategoryID"];
				myProductDetails.Archived = (bool)result["Archived"];
			}
			result.Close();

            return myProductDetails;
        }

        //*******************************************************
        //
        // ProductsDB.GetProductsAlsoPurchased() Method <a name="GetProductsAlsoPurchased"></a>
        //
        // The GetPGetProductsAlsoPurchasedroducts method returns a struct containing
        // a forward-only, read-only DataReader.  This displays a list of other products
        // also purchased with a specified product  The SQLDataReaderResult struct also
        // returns the SQL connection, which must be explicitly closed after the
        // data from the DataReader is bound into the controls.
        //
        // Other relevant sources:
        //     + <a href="CustomerAlsoBought.htm" style="color:green">CustomerAlsoBought Stored Procedure</a>
        //
        //*******************************************************

        public SqlDataReader GetProductsAlsoPurchased(int productID) {

            // Create Instance of Connection and Command Object
            SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
            SqlCommand myCommand = new SqlCommand("StoreNuke_CustomerAlsoBought", myConnection);

            // Mark the Command as a SPROC
            myCommand.CommandType = CommandType.StoredProcedure;

            // Add Parameters to SPROC
            SqlParameter parameterProductID = new SqlParameter("@ProductID", SqlDbType.Int, 4);
            parameterProductID.Value = productID;
            myCommand.Parameters.Add(parameterProductID);

            // Execute the command
            myConnection.Open();
            SqlDataReader result = myCommand.ExecuteReader(CommandBehavior.CloseConnection);

            // Return the datareader result
            return result;
        }

        //*******************************************************
        //
        // ProductsDB.GetMostPopularProductsOfWeek() Method <a name="GetMostPopularProductsOfWeek"></a>
        //
        // The GetMostPopularProductsOfWeek method returns a struct containing a 
        // forward-only, read-only DataReader containing the most popular products 
        // of the week within the Commerce Starter Kit Products database.  
        // The SQLDataReaderResult struct also returns the
        // SQL connection, which must be explicitly closed after the
        // data from the DataReader is bound into the controls.
        //
        // Other relevant sources:
        //     + <a href="ProductsMostPopular.htm" style="color:green">ProductsMostPopular Stored Procedure</a>
        //
        //*******************************************************

        public SqlDataReader GetMostPopularProductsOfWeek() {

            // Create Instance of Connection and Command Object
            SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
            SqlCommand myCommand = new SqlCommand("StoreNuke_ProductsMostPopular", myConnection);

            // Mark the Command as a SPROC
            myCommand.CommandType = CommandType.StoredProcedure;

            // Execute the command
            myConnection.Open();
            SqlDataReader result = myCommand.ExecuteReader(CommandBehavior.CloseConnection);

            // Return the datareader result
            return result;
        }

        //*******************************************************
        //
        // ProductsDB.SearchProductDescriptions() Method <a name="SearchProductDescriptions"></a>
        //
        // The SearchProductDescriptions method returns a struct containing
        // a forward-only, read-only DataReader.  This displays a list of all
        // products whose name and/or description contains the specified search
        // string. The SQLDataReaderResult struct also returns the SQL connection,
        // which must be explicitly closed after the data from the DataReader
        // is bound into the controls.
        //
        // Other relevant sources:
        //     + <a href="ProductSearch.htm" style="color:green">ProductSearch Stored Procedure</a>
        //
        //*******************************************************

        public SqlDataReader SearchProductDescriptions(string searchString) {

            // Create Instance of Connection and Command Object
            SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
            SqlCommand myCommand = new SqlCommand("StoreNuke_ProductSearch", myConnection);

            // Mark the Command as a SPROC
            myCommand.CommandType = CommandType.StoredProcedure;

            // Add Parameters to SPROC
            SqlParameter parameterSearch = new SqlParameter("@Search", SqlDbType.NVarChar, 255);
            parameterSearch.Value = searchString;
            myCommand.Parameters.Add(parameterSearch);

            // Execute the command
            myConnection.Open();
            SqlDataReader result = myCommand.ExecuteReader(CommandBehavior.CloseConnection);

            // Return the datareader result
            return result;
        }

		public int DeleteCategory(int categoryID) 
		{
			// Create Instance of Connection and Command Object
			SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
			SqlCommand myCommand = new SqlCommand("StoreNuke_DeleteCategory", myConnection);

			// Mark the Command as a SPROC
			myCommand.CommandType = CommandType.StoredProcedure;

			// Add Parameters to SPROC
			SqlParameter parameterCategoryID = new SqlParameter("@CategoryID", SqlDbType.Int, 4);
			parameterCategoryID.Value = categoryID;
			myCommand.Parameters.Add(parameterCategoryID);

			SqlParameter parameterMessage = new SqlParameter("@Message", SqlDbType.Int, 4);
			parameterMessage.Direction = ParameterDirection.Output;
			myCommand.Parameters.Add(parameterMessage);

			try
			{ 
				// Open the connection and execute the Command
				myConnection.Open();
				myCommand.ExecuteNonQuery();
				myConnection.Close();

				return (int)parameterMessage.Value;
			}
			catch (Exception e)
			{
				return 0;
			}
		}


		public void UpdateCategory(int categoryID, string categoryName, string categoryDescription, bool archived) 
		{

			// Create Instance of Connection and Command Object
			SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
			SqlCommand myCommand = new SqlCommand("StoreNuke_UpdateCategory", myConnection);

			// Mark the Command as a SPROC
			myCommand.CommandType = CommandType.StoredProcedure;

			// Add Parameters to SPROC
			SqlParameter parameterCategoryID = new SqlParameter("@CategoryID", SqlDbType.Int, 4);
			parameterCategoryID.Value = categoryID;
			myCommand.Parameters.Add(parameterCategoryID);
    
    
			SqlParameter parameterCategoryName = new SqlParameter("@CategoryName", SqlDbType.NVarChar, 50);
			parameterCategoryName.Value = categoryName;
			myCommand.Parameters.Add(parameterCategoryName);
    
    
			SqlParameter parameterCategoryDescription = new SqlParameter("@CategoryDescription", SqlDbType.NVarChar, 500);
			parameterCategoryDescription.Value = categoryDescription;
			myCommand.Parameters.Add(parameterCategoryDescription);
    
    
			SqlParameter parameterArchived = new SqlParameter("@Archived", SqlDbType.Bit);
			parameterArchived.Value = archived;
			myCommand.Parameters.Add(parameterArchived);

			// Open the connection and execute the Command
			myConnection.Open();
			myCommand.ExecuteNonQuery();
			myConnection.Close();
		}

		public void AddCategory(string categoryName, string categoryDescription, bool archived) 
		{

			// Create Instance of Connection and Command Object
			SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
			SqlCommand myCommand = new SqlCommand("StoreNuke_AddCategory", myConnection);

			// Mark the Command as a SPROC
			myCommand.CommandType = CommandType.StoredProcedure;

			// Add Parameters to SPROC
			SqlParameter parameterCategoryName = new SqlParameter("@CategoryName", SqlDbType.NVarChar, 50);
			parameterCategoryName.Value = categoryName;
			myCommand.Parameters.Add(parameterCategoryName);
    
    
			SqlParameter parameterCategoryDescription = new SqlParameter("@CategoryDescription", SqlDbType.NVarChar, 500);
			parameterCategoryDescription.Value = categoryDescription;
			myCommand.Parameters.Add(parameterCategoryDescription);
    
    
			SqlParameter parameterArchived = new SqlParameter("@Archived", SqlDbType.Bit);
			parameterArchived.Value = archived;
			myCommand.Parameters.Add(parameterArchived);

			// Open the connection and execute the Command
			myConnection.Open();
			myCommand.ExecuteNonQuery();
			myConnection.Close();
		}

		public void AddProduct(int categoryID, string modelNumber, string modelName, string productImage, decimal unitCost, string description, bool archived) 
		{

			// Create Instance of Connection and Command Object
			SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
			SqlCommand myCommand = new SqlCommand("StoreNuke_AddProduct", myConnection);

			// Mark the Command as a SPROC
			myCommand.CommandType = CommandType.StoredProcedure;

			// Add Parameters to SPROC
			SqlParameter parameterCategoryID = new SqlParameter("@CategoryID", SqlDbType.Int, 4);
			parameterCategoryID.Value = categoryID;
			myCommand.Parameters.Add(parameterCategoryID);
			
			SqlParameter parameterModelNumber = new SqlParameter("@ModelNumber", SqlDbType.NVarChar, 50);
			parameterModelNumber.Value = modelNumber;
			myCommand.Parameters.Add(parameterModelNumber);
			
			SqlParameter parameterModelName = new SqlParameter("@ModelName", SqlDbType.NVarChar, 50);
			parameterModelName.Value = modelName;
			myCommand.Parameters.Add(parameterModelName);
			
			SqlParameter parameterProductImage = new SqlParameter("@ProductImage", SqlDbType.NVarChar, 50);
			parameterProductImage.Value = productImage;
			myCommand.Parameters.Add(parameterProductImage);			
			
			SqlParameter parameterUnitCost = new SqlParameter("@UnitCost", SqlDbType.Money, 8);
			parameterUnitCost.Value = unitCost;
			myCommand.Parameters.Add(parameterUnitCost);
			
			SqlParameter parameterDescription = new SqlParameter("@Description", SqlDbType.Text);
			parameterDescription.Value = description;
			myCommand.Parameters.Add(parameterDescription);
    
			SqlParameter parameterArchived = new SqlParameter("@Archived", SqlDbType.Bit);
			parameterArchived.Value = archived;
			myCommand.Parameters.Add(parameterArchived);

			// Open the connection and execute the Command
			myConnection.Open();
			myCommand.ExecuteNonQuery();
			myConnection.Close();
		}

		public void UpdateProduct(int productID, int categoryID, string modelNumber, string modelName, string productImage, decimal unitCost, string description, bool archived) 
		{

			// Create Instance of Connection and Command Object
			SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
			SqlCommand myCommand = new SqlCommand("StoreNuke_UpdateProduct", myConnection);

			// Mark the Command as a SPROC
			myCommand.CommandType = CommandType.StoredProcedure;

			// Add Parameters to SPROC
			SqlParameter parameterProductID = new SqlParameter("@ProductID", SqlDbType.Int, 4);
			parameterProductID.Value = productID;
			myCommand.Parameters.Add(parameterProductID);
			
			SqlParameter parameterCategoryID = new SqlParameter("@CategoryID", SqlDbType.Int, 4);
			parameterCategoryID.Value = categoryID;
			myCommand.Parameters.Add(parameterCategoryID);			
			
			SqlParameter parameterModelNumber = new SqlParameter("@ModelNumber", SqlDbType.NVarChar, 50);
			parameterModelNumber.Value = modelNumber;
			myCommand.Parameters.Add(parameterModelNumber);
			
			SqlParameter parameterModelName = new SqlParameter("@ModelName", SqlDbType.NVarChar, 50);
			parameterModelName.Value = modelName;
			myCommand.Parameters.Add(parameterModelName);
			
			SqlParameter parameterProductImage = new SqlParameter("@ProductImage", SqlDbType.NVarChar, 50);
			parameterProductImage.Value = productImage;
			myCommand.Parameters.Add(parameterProductImage);			
			
			SqlParameter parameterUnitCost = new SqlParameter("@UnitCost", SqlDbType.Money, 8);
			parameterUnitCost.Value = unitCost;
			myCommand.Parameters.Add(parameterUnitCost);
			
			SqlParameter parameterDescription = new SqlParameter("@Description", SqlDbType.Text);
			parameterDescription.Value = description;
			myCommand.Parameters.Add(parameterDescription);
    
			SqlParameter parameterArchived = new SqlParameter("@Archived", SqlDbType.Bit);
			parameterArchived.Value = archived;
			myCommand.Parameters.Add(parameterArchived);

			// Open the connection and execute the Command
			myConnection.Open();
			myCommand.ExecuteNonQuery();
			myConnection.Close();
		}

		public int DeleteProduct(int productID) 
		{

			// Create Instance of Connection and Command Object
			SqlConnection myConnection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
			SqlCommand myCommand = new SqlCommand("StoreNuke_DeleteProduct", myConnection);

			// Mark the Command as a SPROC
			myCommand.CommandType = CommandType.StoredProcedure;

			// Add Parameters to SPROC
			SqlParameter parameterProductID = new SqlParameter("@ProductID", SqlDbType.Int, 4);
			parameterProductID.Value = productID;
			myCommand.Parameters.Add(parameterProductID);

			SqlParameter parameterMessage = new SqlParameter("@Message", SqlDbType.Int, 4);
			parameterMessage.Direction = ParameterDirection.Output;
			myCommand.Parameters.Add(parameterMessage);

			try
			{ 
				// Open the connection and execute the Command
				myConnection.Open();
				myCommand.ExecuteNonQuery();
				myConnection.Close();

				return (int)parameterMessage.Value;
			}
			catch (Exception e)
			{
				return 0;
			}
		}
    }
}